package jpm.common;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.ArrayList;
import java.util.List;

import jpm.common.JPMException.ErrorCode;

import org.junit.Test;

public class ListOfListBuilderTest {

	@Test
	public void appendArray() {
		List<List<Integer>> listOfList = ListOfListBuilder.getBuilder()
				.append(1, 2, 3).append(100).get();

		assertEquals(2, listOfList.size());
		List<Integer> list = listOfList.get(0);
		assertEquals(3, list.size());
		assertEquals(1, list.get(0).intValue());
		assertEquals(2, list.get(1).intValue());
		assertEquals(3, list.get(2).intValue());

		list = listOfList.get(1);
		assertEquals(1, list.size());
		assertEquals(100, list.get(0).intValue());
	}

	@Test
	public void appendList() {

		List<Integer> list1 = new ArrayList<>();
		list1.add(1);
		list1.add(2);
		list1.add(3);

		List<Integer> list2 = new ArrayList<>();
		list2.add(100);

		List<List<Integer>> listOfList = ListOfListBuilder.getBuilder()
				.append(list1).append(list2).get();

		assertEquals(2, listOfList.size());
		List<Integer> list = listOfList.get(0);
		assertEquals(3, list.size());
		assertEquals(1, list.get(0).intValue());
		assertEquals(2, list.get(1).intValue());
		assertEquals(3, list.get(2).intValue());

		list = listOfList.get(1);
		assertEquals(1, list.size());
		assertEquals(100, list.get(0).intValue());
	}

	@Test
	public void appendStrings() {

		List<String> strings = new ArrayList<>();
		strings.add("1 2  3 ");
		strings.add("100 ");

		List<List<Integer>> listOfList = ListOfListBuilder.getBuilder()
				.append(strings, "\\s+").get();

		assertEquals(2, listOfList.size());
		List<Integer> list = listOfList.get(0);
		assertEquals(3, list.size());
		assertEquals(1, list.get(0).intValue());
		assertEquals(2, list.get(1).intValue());
		assertEquals(3, list.get(2).intValue());

		list = listOfList.get(1);
		assertEquals(1, list.size());
		assertEquals(100, list.get(0).intValue());
	}

	@Test
	public void appendStrings_invalid_throwsInvalidInput() {

		List<String> strings = new ArrayList<>();
		strings.add("1 2 37");
		strings.add("100b");

		try {
			ListOfListBuilder.getBuilder().append(strings, "\\s+").get();
			assertTrue(false);
		} catch (JPMException ex) {
			assertEquals("invalid input", ErrorCode.ERROR_INVALID_INPUT,
					ex.getErrorCode());
		}
	}

	@Test
	public void appendStrings_emptyList_noException() {

		List<String> strings = new ArrayList<>();

		List<List<Integer>> numbers = ListOfListBuilder.getBuilder()
				.append(strings, "\\s+").get();
		
		assertEquals(0, numbers.size());		
	}
	
	@Test
	public void appendStrings_emptyLine_throwsInvalidInput() {

		List<String> strings = new ArrayList<>();
		strings.add("1 2 37");
		strings.add(""); //empty line

		try {
			ListOfListBuilder.getBuilder().append(strings, "\\s+").get();
			assertTrue(false);
		} catch (JPMException ex) {
			assertEquals("invalid input", ErrorCode.ERROR_INVALID_INPUT,
					ex.getErrorCode());
		}
	}

	@Test
	public void appendStrings_emptyRegex_throwsAssertFail() {

		List<String> strings = new ArrayList<>();
		strings.add("1 2 37");
		strings.add("100b");

		try {
			ListOfListBuilder.getBuilder().append(strings, "").get();
			assertTrue(false);
		} catch (JPMException ex) {
			assertEquals("invalid input", ErrorCode.ERROR_ASSERT_FAIL,
					ex.getErrorCode());
		}
	}

	@Test
	public void get() {
		// already covered by addList test
		assertTrue(true);
	}
}
